using System;
using System.Collections.Generic;
using System.Text;

#nullable enable

public sealed class SubField
{
    public char Code { get; set; }
    public string? Value { get; set; }

    public SubField()
    {
    }

    public SubField(char code, string? value = null)
    {
        Code = code;
        Value = value;
    }

    public override string ToString()
    {
        return $"^{Code}{Value}";
    }
}

public sealed class Field
{
    public int Tag { get; set; }
    public List<SubField> SubFields { get; } = new();

    public Field()
    {
    }

    public Field(int tag)
    {
        Tag = tag;
    }

    public string? GetFirstSubFieldValue(char code)
    {
        foreach (var subField in SubFields)
        {
            if (subField.Code == code)
            {
                return subField.Value;
            }
        }

        return null;
    }

    public void SetFirstSubFieldValue(char code, string? value)
    {
        foreach (var subField in SubFields)
        {
            if (subField.Code == code)
            {
                subField.Value = value;
                return;
            }
        }

        var newSubField = new SubField(code, value);
        SubFields.Add(newSubField);
    }

    public override string ToString()
    {
        var result = new StringBuilder();
        result.Append($"{Tag}#");
        foreach (var subField in SubFields)
        {
            result.Append(subField);
        }

        return result.ToString();
    }
}

[AttributeUsage(AttributeTargets.Class)]
public sealed class GenerateAccessorAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public sealed class SubFieldAttribute : Attribute
{
    public char Code { get; }

    public SubFieldAttribute(char code)
    {
        Code = code;
    }
}

namespace Some.Complex.Space {

    [GenerateAccessor]
    public partial class Person
    {
        [SubField('a')]
        public string? Name { get; set; }

        [SubField('b')]
        public int Age { get; set; }

        partial void FromFieldInternal(Field field);
        partial void ToFieldInternal(Field field);

        public void FromField(Field field) => FromFieldInternal(field);

        public void ToField(Field field) => ToFieldInternal(field);

        public override string ToString()
        {
            return $"{nameof(Name)}: '{Name}', {nameof(Age)}: {Age}";
        }
    }

}

namespace Some.Other.Space {

    [GenerateAccessor]
    public partial class Something
    {
        [SubField('c')]
        public string? Index { get; set; }

        [SubField('d')]
        public int Amount { get; set; }

        partial void FromFieldInternal(Field field);
        partial void ToFieldInternal(Field field);

        public void FromField(Field field) => FromFieldInternal(field);

        public void ToField(Field field) => ToFieldInternal(field);

        public override string ToString()
        {
            return $"{nameof(Name)}: '{Name}', {nameof(Age)}: {Age}";
        }
    }

}

public class Program
{
    public static void Main(string[] args)
    {
        var field = new Field(100);
        field.SubFields.Add(new SubField('a', "Matroskin"));
        field.SubFields.Add(new SubField('b', "2"));

        var person = new Person();
        person.FromField(field);
        Console.WriteLine(person);

        Console.WriteLine();
    }
}
